package br.requisiteworks.seguranca.modelo.dao.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import br.requisiteworks.seguranca.modelo.Funcao;
import br.requisiteworks.seguranca.modelo.dao.FuncaoDao;
import br.requisiteworks.util.persistencia.ErroBancoDados;
import br.requisiteworks.util.persistencia.ResultadoVazio;

@Repository
public class JpaFuncaoDao implements FuncaoDao {

	@PersistenceContext
	private EntityManager em;

	public List<Funcao> select() throws ResultadoVazio {
		TypedQuery<Funcao> queryFuncao = em.createQuery(
				"SELECT OBJECT(f) FROM Funcao f", Funcao.class);
		List<Funcao> funcoes = queryFuncao.getResultList();

		if (funcoes == null || funcoes.isEmpty()) {
			throw new ResultadoVazio(
					"Nao foi encontrado Funcao registrado no banco de dados.");
		}

		return funcoes;
	}

	public Funcao select(int numero) throws ResultadoVazio {
		TypedQuery<Funcao> queryFuncao = em.createQuery(
				"SELECT OBJECT(f) FROM Funcao f WHERE f.numero=:numero",
				Funcao.class);

		queryFuncao.setParameter("numero", numero);
		try {
			return queryFuncao.getSingleResult();
		} catch (NoResultException e) {
			throw new ResultadoVazio("Nao foi encontrada Funcao com numero = "
					+ numero);
		}
	}

	public Funcao select(String nome) throws ResultadoVazio {
		TypedQuery<Funcao> queryFuncao = em.createQuery(
				"SELECT OBJECT(f) FROM Funcao f WHERE f.nome=:nome",
				Funcao.class);

		queryFuncao.setParameter("nome", nome);
		try {
			return queryFuncao.getSingleResult();
		} catch (NoResultException e) {
			throw new ResultadoVazio("Nao foi encontrada Funcao com nome = "
					+ nome);
		}
	}

	@Transactional
	public void insert(Funcao funcao) throws ErroBancoDados {
		try {
			em.persist(funcao);
			em.flush();
		} catch (PersistenceException e) {
			throw new ErroBancoDados("Ocorreu um erro ao adicionar funcao: "
					+ funcao, e);
		}
	}
}
